import { Chat, ChatMessage } from 'components/Chat';
import React from 'react';
import { JSONObject } from 'admin/schema/common';
import { CallTaskInfoMsg, DiaogueMsg } from 'admin/schema/SocketMessage';
import { ManListenCall, ManListenCallSession } from 'admin/schema/Task';
import { getSocket } from 'servers/socket';

import qs from 'query-string';
import { getStateDom } from '../../components/TaskTool';
import { filterDialogue, webDebug } from 'utils/tools';
import { updateChatShow } from './updateChatShow';
import { Empty } from 'antd';

interface ManualListenProp {
  taskId: number;
}

interface ManualListenState extends ManualListenProp {
  /**
   * 模块页面数据
   */
  callInfo?: ManListenCall;
  /**
   * 当前所有的通话数据记录
   */
  currentRecord: ManListenCallSession[];
  /**展示通话数组,记录callRecordId */
  activeChatArr: string[];
}
/**人工监听-改版：
 * 改版标签卡切换逻辑
 * 并发数为4时，数组存4个sessions，默认展示2个，隐藏2个 */
export class ManualListen extends React.Component<ManualListenProp, ManualListenState> {
  /**
   * 回话记录控件的引用集
   */
  private refGroup: React.RefObject<any>[];

  /**
   * 聊天缓存
   * 在实际业务中，可能会同时有很多呼叫/通话，但是界面上只有两个聊天回话窗口，记录一个缓存将收到的但是不能渲染到界面的会话消息保存起来，已保证切换聊天窗口后信息的完整度
   */
  private chatCache: Map<string, ChatMessage[]>;

  constructor(prop: ManualListenProp) {
    super(prop);
    this.chatCache = new Map();

    this.refGroup = [];
    this.state = {
      ...prop,
      callInfo: {} as any,
      currentRecord: [],
      activeChatArr: [],
    };
  }

  componentDidMount() {
    this.addSocketEvent();
    // mock数据
    // const data = {
    //   // mock数据
    //   countComplete: 19,
    //   countProcess: 2,
    //   sessions: [
    //     {
    //       answerTime: '2021/11/12 13:08:45',
    //       callId: '67196',
    //       callRecordId: '20211112130230960C7Rvzt7T',
    //       callSerialNumber: '00012111121308451660',
    //       calledName: '刘菲',
    //       inviteTime: '2021/11/12 13:08:45',
    //       number: '19900000014',
    //       ringTime: '1970/01/01 08:00:00',
    //       state: 2,
    //     },
    //     {
    //       answerTime: '2021/11/12 13:08:45',
    //       callId: '67197',
    //       callRecordId: '20211112130230960coYeIhXC',
    //       callSerialNumber: '00012111121308451661',
    //       calledName: '洋洋',
    //       inviteTime: '2021/11/12 13:08:45',
    //       number: '19900000016',
    //       ringTime: '1970/01/01 08:00:00',
    //       state: 2,
    //     },
    //     {
    //       answerTime: '2021/11/12 13:08:45',
    //       callId: '67198',
    //       callRecordId: '20211112130230960coYeIhok',
    //       callSerialNumber: '00012111121308451662',
    //       calledName: '郑凯',
    //       inviteTime: '2021/11/12 13:08:45',
    //       number: '19900000019',
    //       ringTime: '1970/01/01 08:00:00',
    //       state: 2,
    //     },
    //     {
    //       answerTime: '2021/11/12 13:08:45',
    //       callId: '67199',
    //       callRecordId: '2021456130230960coYeIhok',
    //       callSerialNumber: '10012111121308451662',
    //       calledName: '郑凯1',
    //       inviteTime: '2021/11/12 13:08:45',
    //       number: '19900000023',
    //       ringTime: '1970/01/01 08:00:00',
    //       state: 2,
    //     },
    //     {
    //       answerTime: '2021/11/12 13:08:45',
    //       callId: '67120',
    //       callRecordId: '3021456130230960coYeIhok',
    //       callSerialNumber: '20012111121308451662',
    //       calledName: '郑凯2',
    //       inviteTime: '2021/11/12 13:08:45',
    //       number: '19900000026',
    //       ringTime: '1970/01/01 08:00:00',
    //       state: 2,
    //     },
    //     {
    //       answerTime: '2021/11/12 13:08:45',
    //       callId: '67125',
    //       callRecordId: '4621456130230960coYeIhok',
    //       callSerialNumber: '30012111121308451662',
    //       calledName: '郑凯3',
    //       inviteTime: '2021/11/12 13:08:45',
    //       number: '19900000029',
    //       ringTime: '1970/01/01 08:00:00',
    //       state: 2,
    //     },
    //     {
    //       answerTime: '2021/11/12 13:08:45',
    //       callId: '67126',
    //       callRecordId: '5621456130230960coYeIhok',
    //       callSerialNumber: '40012111121308451662',
    //       calledName: '郑凯4',
    //       inviteTime: '2021/11/12 13:08:45',
    //       number: '19900000030',
    //       ringTime: '1970/01/01 08:00:00',
    //       state: 2,
    //     },
    //     {
    //       answerTime: '2021/11/12 13:08:45',
    //       callId: '67189',
    //       callRecordId: '6621456130230960coYeIhok',
    //       callSerialNumber: '50012111121308451662',
    //       calledName: '郑凯5',
    //       inviteTime: '2021/11/12 13:08:45',
    //       number: '19900000040',
    //       ringTime: '1970/01/01 08:00:00',
    //       state: 2,
    //     },
    //     {
    //       answerTime: '2021/11/12 13:08:45',
    //       callId: '87189',
    //       callRecordId: '6621456130230960coYeImek',
    //       callSerialNumber: '50012111121308451634',
    //       calledName: '郑凯6',
    //       inviteTime: '2021/11/12 13:08:45',
    //       number: '2344000000',
    //       ringTime: '1970/01/01 08:00:00',
    //       state: 2,
    //     },
    //     {
    //       answerTime: '2021/11/12 13:08:45',
    //       callId: '89082',
    //       callRecordId: '6621456130230960coYe1e12',
    //       callSerialNumber: '500121111213084529092',
    //       calledName: '郑凯7',
    //       inviteTime: '2021/11/12 13:08:45',
    //       number: '2344000230',
    //       ringTime: '1970/01/01 08:00:00',
    //       state: 2,
    //     },
    //   ],
    //   taskId: '2960',
    // };

    // this.setState({
    //   callInfo: data as any,
    //   currentRecord: data.sessions as any,
    //   activeChatArr: [data.sessions[0].callRecordId, data.sessions[1].callRecordId],
    // });
  }
  componentWillUnmount = () => {
    this.removeSocketEvent();
    this.setState = (state, callback) => {
      return;
    };
  };

  /**
   * 绑定socket事件
   * dialogueContentEvent： 获取单句会话消息，渲染至页面
   * callTaskStatusEvent： 获取当前机器人正在 呼叫/通话 的列表并渲染
   */
  private addSocketEvent() {
    console.log('人工监听-推送事件->>>>socket事件-开始');
    const socket = getSocket();
    socket.addEvent('dialogueContentEvent', (data: JSONObject) => {
      this.onReceiveMsg(data as DiaogueMsg);
    });
    socket.addEvent('callTaskStatusEvent', (data: JSONObject) => {
      const currentId = qs.parse(window.location.search).id;
      if (data.taskId.toString() !== currentId) {
        return;
      }
      console.log('当前任务推送数据', data);
      // 存储当前任务的推送信息
      const newRecords = [...data.sessions];
      const count = newRecords.length;
      // 当count为0时，说明当前没有正在进行的通话，不显示
      if (count) {
        // 根据sessions个数创建chartRef
        this.refGroup = [];
        for (let j = 0; j < count; j++) {
          // session中出现的通话记录条数，添加ref
          const chatRef_j = React.createRef<any>();
          this.refGroup.push(chatRef_j);
        }
        const activeChatArr = updateChatShow(newRecords, this.state.activeChatArr);
        // 更新数据
        this.setState({
          callInfo: data as CallTaskInfoMsg,
          currentRecord: newRecords,
          activeChatArr,
        });
      } else {
        // 推送为空时，还原界面
        console.log('socket推送的任务sessions为空，页面显示清屏>>>>clear********');
        this.setState({
          callInfo: data as CallTaskInfoMsg,
          currentRecord: [],
          activeChatArr: [],
        });
      }
    });
  }
  /** 卸载socket事件*/
  private removeSocketEvent() {
    console.log('人工监听-推送事件->>>>socket事件-删除');
    const socket = getSocket();
    socket.removeEvent(['dialogueContentEvent', 'callTaskStatusEvent']);
  }
  /**
   * 收到会话的socket消息后，将数据处理一遍格式，转为Chat组件接受的数据格式，渲染会话消息并记录到缓存中
   */
  private onReceiveMsg(data: DiaogueMsg) {
    console.log('接收到的聊天socket*****data===', data.callId, data);
    const cache = this.chatCache;
    const callRecordId = (data as DiaogueMsg).callRecordId;
    const record = cache.get(callRecordId) || [];

    const speakerMap = {
      '0': 'called',
      '1': 'caller',
      '2': 'man',
    };
    // index为0是开场语
    record.push({
      index: data.index,
      role: speakerMap[data.speaker as '0' | '1' | '2'] as 'called' | 'caller' | 'man',
      message: data.content,
      sound: data.url,
      status: data.status,
      callRecordId,
    });
    // 通话记录拼接后，需要根据index去重
    const newRecord = filterDialogue(record as ChatMessage[]);
    cache.set(callRecordId, newRecord);
    const refGroup = this.refGroup;
    if (refGroup.length) {
      refGroup.forEach((ref, index) => {
        // 目标元素：根据callRecordId在聊天记录中查找过滤
        if (ref.current?.getCallRecordId() === callRecordId) {
          ref.current?.setRecord(newRecord);
        }
      });
    }
  }

  /**
   * 根据callRecordId获得一段对话
   */
  private getChatMsg(callRecordId: string): ChatMessage[] {
    return this.chatCache.get(callRecordId) || [];
  }

  /**
   * Chat组件点击查看历史后，将历史会话信息填入缓存中
   */
  private onGetHistory(msg: ChatMessage[], callRecordId: string, callSerialNumber: string): void {
    const currentRecord = this.state.currentRecord;
    this.chatCache.set(callRecordId, msg);
    if (!currentRecord[0] && !currentRecord[1]) {
      return;
    }
    const aimRef = currentRecord.find(item => item && item.callRecordId === callRecordId);
    if (aimRef) {
      const i = currentRecord.indexOf(aimRef);
      this.refGroup[i].current?.setRecord(msg);
    }
  }

  /**界面交互：激活标签卡，高亮右侧对应通话内容 */
  private activeItem(callRecordId: string) {
    const arr = [...this.state.activeChatArr];

    if (arr[0] && arr[0] === callRecordId) {
      console.log('高亮元素被点击，返回**over');
      return;
    }

    // 查找当前展示的聊天数组，例如：[1,2]
    // callRecordId加入展示数组，放第一个，即是界面高亮的元素，例如：3
    console.log('点击切换，通话流水号*****', callRecordId);

    // 展示聊天窗口不存在该流水号，从队首入队，例如：→[3,1,2]
    arr.unshift(callRecordId);

    if (arr.length >= 2) {
      // 超出2个，从队尾出队，例如：←[3,1]
      arr.pop();
    }
    this.setState({
      activeChatArr: arr,
    });
  }

  render() {
    const { callInfo, currentRecord, activeChatArr } = this.state;

    // 暂无数据
    if (!callInfo || !currentRecord.length || !activeChatArr.length) {
      return <Empty image={Empty.PRESENTED_IMAGE_SIMPLE} imageStyle={{ height: 100 }} />;
    }
    console.log('*【人工监听】界面展示数据更新****', callInfo, currentRecord, activeChatArr);
    /**当前呼叫的所有号码推送信息，推送数量跟创建任务时的并发数有关，如果并发数是8，长度就是8 */
    const { sessions } = callInfo;
    /**通话中 */
    const calling = sessions.filter(item => item.state === 2 || item.state === 3).length;
    /**呼叫中 */
    const incall = sessions.filter(item => item.state === 1).length;

    return (
      <div className="manlisten">
        <div className="manlisten-callrecord">
          <span className="manlisten-incall">通话中{calling}</span>
          <span className="manlisten-waitcall">呼叫中{incall}</span>
          {sessions.map((item, index) => {
            return (
              <div
                className={`manlisten-call-item ${
                  item.callRecordId === activeChatArr[0] ? 'active' : 'notactive'
                }`}
                key={index}
                onClick={() => this.activeItem(item.callRecordId)}
              >
                <div className="manlisten-callitem-header">
                  <span className="manlisten-callitem-callednum">
                    {webDebug && (
                      <b className="debug-style">
                        【{item.callRecordId}】【{item.callId}】
                      </b>
                    )}
                    {item.number}
                  </span>
                  <span className="manlisten-callitem-state">{getStateDom(item.state)}</span>
                </div>
                <div className="detail">
                  <div className="manlisten-callitem-ringtime">
                    <span className="manlisten-callitem-label">接通时间</span>
                    <span>{item.ringTime}</span>
                  </div>
                  <div className="manlisten-callitem-calledname">
                    <span className="manlisten-callitem-label">被叫姓名</span>
                    <span>{item.calledName}</span>
                  </div>
                  <div className="manlisten-callitem-remark">
                    <span className="manlisten-callitem-label">被叫备注</span>
                    <span>{item.calledRemarks}</span>
                  </div>
                </div>
              </div>
            );
          })}
        </div>
        <div className="chat-wrapper">
          {currentRecord &&
            currentRecord.length > 0 &&
            currentRecord.map((chatInfo, index) => (
              // 通话记录-循环展示
              <div
                key={chatInfo.callRecordId ? 'box_' + chatInfo.callRecordId : 'box_' + index}
                className={`manlisten-chat ${
                  chatInfo.callRecordId === activeChatArr[0]
                    ? 'active'
                    : chatInfo.callRecordId === activeChatArr[1]
                    ? 'show'
                    : 'hide'
                }`}
              >
                {/* 接通,有会话内容则显示 */}
                {chatInfo.callRecordId && (
                  <Chat
                    showHistoryLink={true}
                    ref={this.refGroup[index]}
                    callSerialNumber={chatInfo.callSerialNumber}
                    callRecordId={chatInfo.callRecordId}
                    centerCallId={chatInfo.callId}
                    phoneNum={chatInfo.number}
                    status={chatInfo.state}
                    messages={this.getChatMsg(chatInfo.callRecordId)}
                    onGetHistory={this.onGetHistory.bind(this)}
                  />
                )}
              </div>
            ))}
        </div>
      </div>
    );
  }
}
